#include<iostream>
#include<string>
#include"httplib.h"
#include"add_contacts.pb.h"

using namespace std;
using namespace httplib;

//自定义异常类
class ContactException {
public:
    ContactException(std::string str = "A problem") : message(str) {}
    const std::string what() const { return message; }

private:
    std::string message;
};

void printRequest(const add_contacts::RequestContacts& request)
{
    cout << "联系人姓名： " << request.name() << endl;
    cout << "联系人年龄： " << request.age() << endl;
    for(int i = 0;i < request.phone_numbers_size();i++)
    {
        const add_contacts::RequestContacts_Phone& phone = request.phone_numbers(i);
        cout << "phone number" << i+1 << ":" << phone.number();
        cout << "     (" << add_contacts::RequestContacts_Phone_PhoneType_Name(phone.type()) << ")" << endl;
    }
}


//设置uid
static unsigned int random_char() {
    // ⽤于随机数引擎获得随机种⼦
    std::random_device rd; 
    // mt19937是c++11新特性，它是⼀种随机数算法，⽤法与rand()函数类似，但是mt19937具有速度快，周期⻓的特点
    // 作⽤是⽣成伪随机数
    std::mt19937 gen(rd()); 
    // 随机⽣成⼀个整数i 范围[0, 255]
    std::uniform_int_distribution<> dis(0, 255);
    return dis(gen);
 }

 // ⽣成 UUID （通⽤唯⼀标识符）
static std::string generate_hex(const unsigned int len) {
    std::stringstream ss;
    // ⽣成 len 个16进制随机数，将其拼接⽽成
    for (auto i = 0; i < len; i++) {
        const auto rc = random_char();
        std::stringstream hexstream;
        hexstream << std::hex << rc;
        auto hex = hexstream.str();
        ss << (hex.length() < 2 ? '0' + hex : hex);
    }
    return ss.str();
 }

int main()
{
    cout << "-----------------------Server start-------------------------" << endl;

    Server svr;
    svr.Post("/add_contacts", [](const Request &req, Response &res){
        add_contacts::RequestContacts request;
        add_contacts::ResponseContacts response;

        try
        {
            //反序列化请求数据
            if(!request.ParseFromString(req.body))
            {
                throw ContactException("ParseFromString error");
            }

            //业务处理(打印)
            printRequest(request);

            //构造resp
            response.set_success(true);
            response.set_uid(generate_hex(10));

            //序列化resp
            string response_str;
            if(!response.SerializeToString(&response_str))
            {
                throw ContactException("SerializeToString error");
            }

            //设置resp头
            res.status = 200;
            res.body=response_str;
            res.set_header("Content-Type","application/protobuf");
        }
        catch(const ContactException& e)
        {
            res.status = 500;
            response.set_success(false);
            response.set_errmessage(e.what());
            string resp_str;
            if(response.SerializeToString(&resp_str))
            {
                res.body = resp_str;
                res.set_header("Content-Type","application/protobuf");
            }
            cout << "错误信息：" << e.what() << endl;
        }
        
    }) ;

    svr.listen("0.0.0.0", 8080);
   
    svr.stop();
    cout << "-----------------------Server stop-------------------------" << endl;
    return 0;
}